﻿#pragma once

#include <Eigen/Core>
#include <Eigen/Dense>
#include <Eigen/Sparse>

#include <xy/math/matrix.h>

namespace xy
{

namespace utils
{

struct adaptor_eigen
{
    const bool flag;
    const double *data;
    const std::size_t rows;
    const std::size_t cols;

    adaptor_eigen(const Eigen::MatrixXd &mat) : flag(true), data(mat.data()), rows(mat.rows()), cols(mat.cols())
    {
    }

    // 内存顺序相反的矩阵，需要转置
    adaptor_eigen(const math::matxd &mat) : flag(false), data(mat.data()), rows(mat.cols()), cols(mat.rows())
    {
    }

    operator Eigen::MatrixXd() const
    {
        if (flag)
            return Eigen::Map<const Eigen::MatrixXd>(data, rows, cols);
        else
            return Eigen::Map<const Eigen::MatrixXd>(data, cols, rows).transpose();
    }

    operator math::matxd() const
    {
        math::matxd mat(rows, cols);
        std::copy(data, data + rows * cols, mat.data());
        if (flag)
            return mat.transpose();
        else
            return mat;
    }
};

} // namespace utils

} // namespace xy